gusucode.com > 38个VB ICO图标操作小程序源码合集 > 38个VB ICO图标操作小程序源码合集/code/Icon控制专集/DesktopIcons/Readme.txt

    You will note that this works for both Win 9X and WinNT/2000!!!   I take no credit for this code as I found it and altered it only slightly to save the icon positions for a given resolution.   Frankly, I am a novice at API and much of this is over my head.   Here is where I found the code and the author and I've reproduced his post:

http://www.codeguru.com/vb/comments/991.shtml

Ben: bczulowski@hotmail.com

Attribute VB_Name = "mSharedMemory"
Option Explicit
'Some API (SendMessage for example) use pointers to structures to be filled
'with some data. If you're sending such message to window belong to your
'process - no problem. But if you try to send this message to different
'process GPF can occure, because structure address belong to calling process
'memory space and target process can not achive this address. Here is
'work around.
'For Win95/98/ME we can use File Mapping, because OS place mapped files
'into shareable memory space. But we can't use this trick for NT - NT map
'files into calling process memory area. In this case, we can use
'VirtualAllocEx function to reserve memory inside target process.

'=========Checking OS staff=============
Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
End Type
Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (LpVersionInformation As OSVERSIONINFO) As Long

'========= Win95/98/ME Shared memory staff===============
Private Declare Function CreateFileMapping Lib "kernel32" Alias "CreateFileMappingA" (ByVal hFile As Long, ByVal lpFileMappigAttributes As Long, ByVal flProtect As Long, ByVal dwMaximumSizeHigh As Long, ByVal dwMaximumSizeLow As Long, ByVal lpName As String) As Long
Private Declare Function MapViewOfFile Lib "kernel32" (ByVal hFileMappingObject As Long, ByVal dwDesiredAccess As Long, ByVal dwFileOffsetHigh As Long, ByVal dwFileOffsetLow As Long, ByVal dwNumberOfBytesToMap As Long) As Long
Private Declare Function UnmapViewOfFile Lib "kernel32" (lpBaseAddress As Any) As Long
Const STANDARD_RIGHTS_REQUIRED = &HF0000
Const SECTION_QUERY = &H1
Const SECTION_MAP_WRITE = &H2
Const SECTION_MAP_READ = &H4
Const SECTION_MAP_EXECUTE = &H8
Const SECTION_EXTEND_SIZE = &H10
Const SECTION_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED Or SECTION_QUERY Or SECTION_MAP_WRITE Or SECTION_MAP_READ Or SECTION_MAP_EXECUTE Or SECTION_EXTEND_SIZE
Const FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS

'============NT Shared memory staff======================
Private Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Const PROCESS_VM_OPERATION = &H8
Const PROCESS_VM_READ = &H10
Const PROCESS_VM_WRITE = &H20
Const PROCESS_ALL_ACCESS = 0
Private Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Const MEM_COMMIT = &H1000
Const MEM_RESERVE = &H2000
Const MEM_DECOMMIT = &H4000
Const MEM_RELEASE = &H8000
Const MEM_FREE = &H10000
Const MEM_PRIVATE = &H20000
Const MEM_MAPPED = &H40000
Const MEM_TOP_DOWN = &H100000

'==========Memory access constants===========
Private Const PAGE_NOACCESS = &H1&
Private Const PAGE_READONLY = &H2&
Private Const PAGE_READWRITE = &H4&
Private Const PAGE_WRITECOPY = &H8&
Private Const PAGE_EXECUTE = &H10&
Private Const PAGE_EXECUTE_READ = &H20&
Private Const PAGE_EXECUTE_READWRITE = &H40&
Private Const PAGE_EXECUTE_WRITECOPY = &H80&
Private Const PAGE_GUARD = &H100&
Private Const PAGE_NOCACHE = &H200&

Public Function GetMemShared95(ByVal memSize As Long, hFile As Long) As Long
    hFile = CreateFileMapping(&HFFFFFFFF, 0, PAGE_READWRITE, 0, memSize, vbNullString)
    GetMemShared95 = MapViewOfFile(hFile, FILE_MAP_ALL_ACCESS, 0, 0, 0)
End Function

Public Sub FreeMemShared95(ByVal hFile As Long, ByVal lpMem As Long)
    UnmapViewOfFile lpMem
    CloseHandle hFile
End Sub

Public Function GetMemSharedNT(ByVal pid As Long, ByVal memSize As Long, hProcess As Long) As Long
    hProcess = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, pid)
    GetMemSharedNT = VirtualAllocEx(ByVal hProcess, ByVal 0&, ByVal memSize, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
End Function

Public Sub FreeMemSharedNT(ByVal hProcess As Long, ByVal MemAddress As Long, ByVal memSize As Long)
   Call VirtualFreeEx(hProcess, ByVal MemAddress, memSize, MEM_RELEASE)
   CloseHandle hProcess
End Sub

Public Function IsWindowsNT() As Boolean
   Dim verinfo As OSVERSIONINFO
   verinfo.dwOSVersionInfoSize = Len(verinfo)
   If (GetVersionEx(verinfo)) = 0 Then Exit Function
   If verinfo.dwPlatformId = 2 Then IsWindowsNT = True
End Function

''''''''''''''''''''''''''

Attribute VB_Name = "Module1"
Option Explicit

Public Enum SHUFFLE_TYPE
    RANDOM
    SINE
    CIRCLES
'More depend on your fantasy and geomethry knowledge :)
End Enum
'=========Desktop SysListView staff=============
Type POINTAPI
     x As Long
     y As Long
End Type

Private Declare Function FindWindow& Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String)
Private Declare Function FindWindowEx& Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpClassName As String, ByVal lpWindowName As String)
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetWindowLong& Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long)
Const GWL_STYLE = (-16)
Private Const LVS_AUTOARRANGE = &H100

Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)
Private Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long

Private Declare Function SendMessage& Lib "user32" Alias "SendMessageA" (ByVal hWnd&, ByVal wMsg&, ByVal wParam&, lParam As Any)
Private Const LVM_FIRST = &H1000
Private Const LVM_GETTITEMCOUNT& = (LVM_FIRST + 4)
Private Const LVM_SETITEMPOSITION& = (LVM_FIRST + 15)
Private Const LVM_GETITEMPOSITION& = (LVM_FIRST + 16)
Private Const WM_COMMAND = &H111
Private Const IDM_TOGGLEAUTOARRANGE = &H7041

'=============================================================
Dim ptOriginal() As POINTAPI
Dim ptCurrent() As POINTAPI
Dim xScreen As Long, yScreen As Long
Dim bAutoArrange As Boolean

Public Sub ShuffleDesktopIcons(ByVal ShuffleType As SHUFFLE_TYPE)
   Dim h As Long, nCount As Long, i As Long
   Dim FactorX As Single, FactorY As Single, Radius As Single
   Dim x As Long, y As Long, cx As Long, cy As Long
   FactorX = Rnd
   FactorY = Rnd
   Radius = xScreen * Rnd / 2
   h = GetSysLVHwnd
   nCount = SendMessage(h, LVM_GETTITEMCOUNT, 0, 0&)
   For i = 0 To nCount - 1
       Select Case ShuffleType
              Case RANDOM
                   x = Int(Rnd * xScreen)
                   y = Int(Rnd * yScreen)
              Case SINE
                   x = FactorX * xScreen * i \ nCount
                   y = FactorY * yScreen * (1 - Sin(i * 6.28 / nCount)) \ 2
              Case CIRCLES
                   x = xScreen / 2 - Radius * Cos(i * 6.28 / nCount)
                   y = yScreen / 2 - Radius * Sin(i * 6.28 / nCount)
       End Select
       Call SendMessage(h, LVM_SETITEMPOSITION, i, ByVal CLng(x + y * &H10000))
   Next
End Sub

Public Sub RestoreDesktopIcons()
   Dim h As Long, nCount As Long, i As Long
   h = GetSysLVHwnd
   nCount = SendMessage(h, LVM_GETTITEMCOUNT, 0, 0&)
   For i = 0 To nCount - 1
       Call SendMessage(h, LVM_SETITEMPOSITION, i, ByVal CLng(ptOriginal(i).x + ptOriginal(i).y * &H10000))
   Next
   If bAutoArrange Then
      Call SendMessage(GetParent(h), WM_COMMAND, IDM_TOGGLEAUTOARRANGE, ByVal 0&)
   End If
End Sub

Public Function StoreDeskTopInfo() As Boolean
   Dim pid As Long, tid As Long, lStyle As Long
   Dim hProcess As Long, lpSysShared As Long, dwSize As Long
   Dim nCount As Long, lWritten As Long, hFileMapping As Long
   Dim h As Long, i As Long
   h = GetSysLVHwnd
   If h = 0 Then Exit Function
   If (GetWindowLong(h, GWL_STYLE) And LVS_AUTOARRANGE) = LVS_AUTOARRANGE Then
      bAutoArrange = True
      Call SendMessage(GetParent(h), WM_COMMAND, IDM_TOGGLEAUTOARRANGE, ByVal 0&)
   End If
   tid = GetWindowThreadProcessId(h, pid)
   nCount = SendMessage(h, LVM_GETTITEMCOUNT, 0, 0&)
   If nCount = 0 Then Exit Function
   xScreen = Screen.Width \ Screen.TwipsPerPixelX
   yScreen = Screen.Height \ Screen.TwipsPerPixelY
   ReDim ptOriginal(nCount - 1)
   ReDim ptCurrent(nCount - 1)
   dwSize = Len(ptOriginal(0))
   If IsWindowsNT Then
      lpSysShared = GetMemSharedNT(pid, dwSize, hProcess)
      WriteProcessMemory hProcess, ByVal lpSysShared, ptOriginal(0), dwSize, lWritten
      For i = 0 To nCount - 1
          SendMessage h, LVM_GETITEMPOSITION, i, ByVal lpSysShared
          ReadProcessMemory hProcess, ByVal lpSysShared, ptOriginal(i), dwSize, lWritten
      Next i
      FreeMemSharedNT hProcess, lpSysShared, dwSize
   Else
      lpSysShared = GetMemShared95(dwSize, hFileMapping)
      CopyMemory ByVal lpSysShared, ptOriginal(0), dwSize
      For i = 0 To nCount - 1
          SendMessage h, LVM_GETITEMPOSITION, i, ByVal lpSysShared
          CopyMemory ptOriginal(i), ByVal lpSysShared, dwSize
          ptCurrent(i).x = xScreen / 2
          ptCurrent(i).y = yScreen / 2
      Next i
      FreeMemShared95 hFileMapping, lpSysShared
   End If
   StoreDeskTopInfo = True
End Function

Private Function GetSysLVHwnd() As Long
   Dim h As Long
   h = FindWindow("Progman", vbNullString)
   h = FindWindowEx(h, 0, "SHELLDLL_defVIEW", vbNullString)
   GetSysLVHwnd = FindWindowEx(h, 0, "SysListView32", vbNullString)
End Function

'''''''''''''''''''''''''''

VERSION 5.00
Begin VB.Form Form1 
   BorderStyle     =   3  'Fixed Dialog
   Caption         =   "Form1"
   ClientHeight    =   1365
   ClientLeft      =   45
   ClientTop       =   330
   ClientWidth     =   4680
   LinkTopic       =   "Form1"
   MaxButton       =   0   'False
   MinButton       =   0   'False
   ScaleHeight     =   1365
   ScaleWidth      =   4680
   ShowInTaskbar   =   0   'False
   StartUpPosition =   3  'Windows Default
   Begin VB.ComboBox Combo1 
      Height          =   315
      Left            =   2520
      Style           =   2  'Dropdown List
      TabIndex        =   2
      Top             =   240
      Width           =   1875
   End
   Begin VB.Timer Timer1 
      Left            =   4260
      Top             =   60
   End
   Begin VB.CommandButton Command2 
      Caption         =   "Command2"
      Height          =   495
      Left            =   2580
      TabIndex        =   1
      Top             =   780
      Width           =   1815
   End
   Begin VB.CommandButton Command1 
      Caption         =   "Command1"
      Height          =   495
      Left            =   240
      TabIndex        =   0
      Top             =   780
      Width           =   1875
   End
   Begin VB.Label Label1 
      Caption         =   "Label1"
      Height          =   315
      Left            =   240
      TabIndex        =   3
      Top             =   240
      Width           =   1875
   End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Dim bRunning As Boolean

Private Sub Command1_Click()
   If Not bRunning Then
      If StoreDeskTopInfo Then Timer1.Enabled = True
      Caption = "See your desktop dancing!"
      bRunning = True
      Command1.Enabled = False
      Command2.Enabled = True
   End If
End Sub

Private Sub Command2_Click()
   If bRunning Then
      Timer1.Enabled = False
      RestoreDesktopIcons
      bRunning = False
      Caption = "Desktop shuffle sample"
      Command1.Enabled = True
      Command2.Enabled = False
   End If
End Sub

Private Sub Form_Load()
   Timer1.Interval = 200
   Timer1.Enabled = False
   Caption = "Desktop shuffle demo"
   Label1 = "Desktop shuffling type"
   With Combo1
        .AddItem "RANDOM"
        .AddItem "SINE"
        .AddItem "CIRCLES"
        .ListIndex = 0
   End With
   Command1.Caption = "&Start"
   Command2.Caption = "&Stop"
   Command1.Enabled = True
   Command2.Enabled = False
End Sub

Private Sub Form_Unload(Cancel As Integer)
   If bRunning Then RestoreDesktopIcons
End Sub

Private Sub Timer1_Timer()
    ShuffleDesktopIcons Combo1.ListIndex
End Sub

''''''''''''''''''''''''''''

enjoy !!!